from itertools import takewhile
import tkinter, socket
import tkinter.messagebox
import threading

from tkinter import *
from random import randint

# 기본 socket 커넥션 설정
HOST = "127.0.0.1"
PORT = 8112
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
debug = 0
window = tkinter.Tk()
window.configure(background="#a1abcd")
window.title("베이비소마  클라이언트")
window.geometry('1400x700') #프로그램 사이즈 설정
user_id = "" #로그인 유저 아이디 저장

dice_flag = False

recv_chat_window = tkinter.Text(window) #서버에서 받은 데이터를 보여주는 창
send_chat_data = tkinter.Entry(window) #사용자의 입력을 받는 창

# 게임 정보 창
Game_Info_window = tkinter.Text(window, width = 60, height = 10)

User_Info_money = 10000
Enemy_Info_money = 10000
User_Info_location = []
Enemy_Info_location = []
User_build = []
Enemy_build = []

playerpoint = [[550, 510, 550, 550]]

canvas = tkinter.Canvas(width = 600, height = 600)

map_image = tkinter.PhotoImage(file='map.gif')
image2 = tkinter.PhotoImage(file='player1.gif')
image3 = tkinter.PhotoImage(file='player2.gif')
image4 = tkinter.PhotoImage(file='flag.gif')
image5 = tkinter.PhotoImage(file='flag2.gif')

winlabel = tkinter.Label(window, text="승리했습니다!", bg="#383a39", fg="#a1abcd", font=("Helvetica", 16))
loselabel = tkinter.Label(window, text="패배했습니다", bg="#383a39", fg="#a1abcd", font=("Helvetica", 16))


def dialog_yes():
    global t_money, t_location

    dialogLabel.pack_forget()
    dialog_y_btn.pack_forget()
    dialog_n_btn.pack_forget()

    print("------BUY------")

    message =  "EVENT " + "BUY " + str(t_money) + " " + t_location
    s.send(message.encode('utf-8'))

    print(message)

    setGameInfo()

def dialog_no():
    dialogLabel.pack_forget()
    dialog_y_btn.pack_forget()
    dialog_n_btn.pack_forget()

    print("------NOT BUY------")

    message =  "EVENT " + "NOTBUY " + str(t_money) + " " + t_location
    s.send(message.encode('utf-8'))

    print(message)

    setGameInfo()

dialogLabel = tkinter.Label(window, text="구매하시겠습니까?", bg="#383a39", fg="#a1abcd", font=("Helvetica", 16))
dialog_y_btn = tkinter.Button(window, text="네", bg="#383a39", fg="#a1abcd", command=dialog_yes)
dialog_n_btn = tkinter.Button(window, text="아니오", bg="#383a39", fg="#a1abcd", command=dialog_no)

t_money = 0
t_location = ""

turn_flag = 0
player_flag = 0
player1_position = 0
player2_position = 0

def gettingMsg():
    global debug, user_id, dice_flag, canvas, player_flag, player1_position, player2_position, t_money, t_location, User_Info_money, User_Info_location, Enemy_Info_location, Enemy_Info_money, loselabel, winlabel, User_build, Enemy_build
    while True:
        recv_data = s.recv(1024).decode('utf-8')
        recv_split_data = recv_data.split(" ") #받은 데이터 파싱하기 위해 문자열 자르기

        if debug is 1: #디버그 모드일때 출력하기 위함
            recv_chat_window.insert(tkinter.INSERT, ">> " + recv_data + '\n')
        else:
            if recv_split_data[0] is 531:
                recv_chat_window.insert(tkinter.INSERT, recv_data + '\n')

        if recv_split_data[0] == '230': #230값을 받았을때 ui바꾼다

            print("------set Game------")

            tkinter.messagebox.showinfo("로그인 결과", "로그인 성공.채팅화면으로 이동합니다")
            user_id = login_id.get()
            labelInst.pack_forget()
            register_id.pack_forget()
            register_password.pack_forget()
            login_id.pack_forget()
            login_password.pack_forget()
            btn_login.pack_forget()
            btn_register.pack_forget()

            Game_Info_window.place(x = 200, y = 500)

            recv_chat_window.place(x=50,y=50)
            send_chat_data.place(x=250,y=450)
            send_chat_data.bind('<Return>', send_data) #텍스트 입력창에 엔터키 이벤트를 바인딩

            btn_dice = tkinter.Button(window, text="주사위", bg="#383a39", fg="#a1abcd",command=dice)
            btn_dice.place(x = 100, y = 600)

            #Image

            canvas.place(x = 700, y = 50)
            canvas.create_image(0, 0, image = map_image, anchor = NW)

            #Game Info

            setGameInfo()


        if recv_split_data[0] == '221': #221값을 받았을때 서비스 종료
            global window
            window.destroy()
            s.close()

        if recv_split_data[0] == '299' or recv_split_data[0] == '231': #299나 231일때 파싱하여 출력
            message = recv_data.split(' ', 2)
            recv_chat_window.insert(tkinter.INSERT, message[2] + '\n')

        if recv_split_data[0] == '233':

            print("------start game------")

            message = recv_data.split(' ')
            print(message[3])
            print(user_id)
            if message[3] == user_id:
                dice_flag = True
                player_flag = 1
            else:
                player_flag = 2

            # 유저 아이디 분석

            move1(0)
            move2(0)

        if recv_split_data[0] == '235':
            dice_flag = True
            print("my turn")
        if recv_split_data[0] == '236': # 236 username 이동한위치 이벤트내용
            print("------User Move Event------")
            print(recv_data)
            player1_position = int(recv_split_data[2])

            canvas.create_image(0, 0, image = map_image, anchor = NW)

            if(player_flag == 1):
                move1(player1_position)
                move2(player2_position)

                build1()
                build2()
            else:
                move2(player1_position)
                move1(player2_position)

                build1()
                build2()

            # location 정보값

            t_money = int(recv_split_data[5])
            t_location = recv_split_data[6]

            if(t_money == 10000):
                print("------Get Money------")
                User_Info_money = User_Info_money + 1000
            elif(t_money == 777):
                print("------황금열쇠------")

                message = "EVENT " + "KEY " + str("0") + t_location
                s.send(message.encode('utf-8'))
                # 777일 경우에 황금열쇠의 반영 결과를 같이 가져오는 걸로? recv_split_data.insert(변동 사항)
                # 아니면

            elif(t_money == 999):
                print("------무인도------")

                message =  "EVENT " + "ISLAND 0 무인도"
                s.send(message.encode('utf-8'))

            elif(t_money == 7):
                print("------홍교수님------")

                message =  "EVENT " + "HONG " + str("0") + t_location
                s.send(message.encode('utf-8'))

            elif(t_money == 6):
                print("------우주여행------")

                message =  "EVENT " + "SPACE " + str("0") + t_location
                s.send(message.encode('utf-8'))

            elif(t_money == 0):
                print("------No event------")

                message = "EVENT " + "NOTBUY " + str("0") + t_location
                s.send(message.encode('utf-8'))

            elif(t_money > 0):
                dialogLabel.pack()
                dialog_y_btn.pack()
                dialog_n_btn.pack()

            elif(t_money < 0):
                print("------Pay out------")

                message = "EVENT " + "TAX " + str("0") + t_location
                s.send(message.encode('utf-8'))

            #이벤트 처리내용을 EVENT ...으로 보내라 
        if recv_split_data[0] == '237': # 상대방 이동한위치
            print("------Enemy Move Event------")
            print(recv_data)
            player2_position = int(recv_split_data[2])

            canvas.create_image(0, 0, image = map_image, anchor = NW)

            print(player2_position)

            if(player_flag == 1):
                move1(player1_position)
                move2(player2_position)

                build1()
                build2()

            else:
                move2(player1_position)
                move1(player2_position)

                build1()
                build2()

        if recv_split_data[0] == '239':
            print("------User Data Event------")
            print(recv_data)

            User_build.append(int(recv_split_data[2]))
            User_Info_money = int(recv_split_data[3])
            User_Info_location.append(recv_split_data[4])
            Enemy_Info_money = int(recv_split_data[5])

            print(User_Info_money)
            print(User_Info_location)
            print(Enemy_Info_money)

            setGameInfo()

            build1()
            build2()

        if recv_split_data[0] == '240':
            print("------Enemy Data Event------")
            print(recv_data)

            Enemy_build.append(int(recv_split_data[2]))
            Enemy_Info_money = int(recv_split_data[3])
            Enemy_Info_location.append(recv_split_data[4])
            User_Info_money = int(recv_split_data[5])

            print(Enemy_Info_money)
            print(Enemy_Info_location)
            print(User_Info_money)

            dice_flag = True

            setGameInfo()

            build1()
            build2()

        if recv_split_data[0] == '250': #USERNAME -> WIN
            print("------WIN EVENT------")
            print(recv_data)

            if recv_split_data[1] == user_id:
                winlabel.pack()
            else:
                loselabel.pack()


        if recv_split_data[0] == '232': #회원가입 성공 메시지
            tkinter.messagebox.showinfo("회원가입 결과", "가입이 완료되었습니다. 로그인 해주세요")
        elif recv_split_data[0] == '510': #회원가입 실패 메시지
            tkinter.messagebox.showinfo("회원가입 결과", "이미 존재하는 아이디입니다. 다른 아이디를 입력하세요")

    s.close()

def print_debug(data): #디버그 모드일때 출력하는 함수
    global debug
    if debug is 1:
        recv_chat_window.insert(tkinter.INSERT, "<< "  + data + '\n')

def send_data(event): #텍스트 입력창에 바인딩된 함수로서 서버에 데이터를 보내는 역할
    global debug, user_id
    message = send_chat_data.get()
    recv_chat_window.insert(tkinter.INSERT, send_chat_data.get() + '\n')
    temp_message = message.split(" ")

    if temp_message[0] == '.list': #사용자의 입력값을 파싱하여 서버에 데이터를 보낸다
        s.send(("LIST").encode('utf-8'))
        print_debug("LIST")
    elif temp_message[0] == '.quit':
        s.send(("QUIT").encode('utf-8'))
        print_debug("QUIT")
    elif temp_message[0] == '.game':
        s.send(("GAME 6").encode('utf-8'))
    elif temp_message[0] == '.debug':
        if debug is 0:
            debug = 1
            recv_chat_window.insert(tkinter.INSERT, "debug mode on" + '\n') #텍스트창에 출력
        else:
            debug = 0
            recv_chat_window.insert(tkinter.INSERT, "debug mode off" + '\n')
    else:
        s.send(("FROM " + user_id + ": " + message).encode('utf-8'))
        print_debug(("FROM " + user_id + ": " + message))

    send_chat_data.delete(0, tkinter.END)

def register(): # btn_register에 반응하는 함수
    str = "REGISTER " + register_id.get() + " " + register_password.get()
    s.send(str.encode('utf-8'))
    register_id.delete(0, tkinter.END)
    register_password.delete(0, tkinter.END)

def login(): # btn_login에 반응하는 함수
    login_message = "USER " + login_id.get() + " " + login_password.get()
    s.send(login_message.encode('utf-8'))

def dice():
    global dice_flag, recv_chat_window

    dice_num = randint(1, 6)
    print(dice_flag)
    if dice_flag:


        print("------dice------")
        print(dice_num)

        Game_Info_window.insert(tkinter.INSERT, "주사위 : " + str(dice_num) + "\n")

        dice_message = "GAME " + str(dice_num)
        s.send(dice_message.encode('utf-8'))
        dice_flag = False

    print(dice_flag)

def move2(move_position):
    global canvas

    print("------Enemy move------")
    print(move_position)

    if move_position == 0:
        canvas.create_image(550, 550, image = image3, anchor = NW)
    elif move_position >= 1 and move_position <= 5:
        canvas.create_image(550, 457 - (77*(move_position-1)), image = image3, anchor = NW)
    elif move_position == 6:
        canvas.create_image(550, 62, image = image3, anchor = NW)
    elif move_position >= 7 and move_position <= 11:
        canvas.create_image(450 - (80*((move_position-1)%6)), 47, image = image3, anchor = NW)
    elif move_position == 12:
        canvas.create_image(35, 62, image = image3, anchor = NW)
    elif move_position >= 13 and move_position <=17:
        canvas.create_image(35, 149 + (77*((move_position-1)%6)), image = image3, anchor = NW)
    elif move_position == 18:
        canvas.create_image(35, 550, image = image3, anchor = NW)
    else:
        canvas.create_image(130 + (77*((move_position-1)%6)), 560, image = image3, anchor = NW)

def move1(move_position):
    global canvas

    if move_position == 0:
        canvas.create_image(550, 510, image = image2, anchor = NW)
    elif move_position >= 1 and move_position <= 5:
        canvas.create_image(550, 417 - (77 * (move_position-1)), image = image2, anchor = NW)
    elif move_position == 6:
        canvas.create_image(550, 22, image = image2, anchor = NW)
    elif move_position >= 7 and move_position <= 11:
        canvas.create_image(450 - (80 * ((move_position-1)%6)), 7, image = image2, anchor = NW)
    elif move_position == 12:
        canvas.create_image(35, 22, image = image2, anchor = NW)
    elif move_position >= 13 and move_position <=17:
        canvas.create_image(35, 109 + (77*((move_position-1)%6)), image = image2, anchor = NW)
    elif move_position == 18:
        canvas.create_image(35, 510, image = image2, anchor = NW)
    else:
        canvas.create_image(130 + (77*((move_position-1)%6)), 520, image = image2, anchor = NW)

def build1():
    global canvas, User_build

    print ("-----BUILD1------")
    for i in User_build:
        print(i)

    for i in User_build:
        if i >= 1 and i <= 5:
            canvas.create_image(550-40, 417 - (77 * (i-1)), image = image4, anchor = NW)
        if i >= 7 and i <= 11:
            canvas.create_image(450 - (80 * ((i-1)%6)), 7+40, image = image4, anchor = NW)
        if i >= 13 and i <=17:
            canvas.create_image(35+40, 109 + (77*((i-1)%6)), image = image4, anchor = NW)
        if i >= 19 and i <=23:
            canvas.create_image(130 + (77*((i-1)%6)), 520-40, image = image4, anchor = NW)

def build2():
    global canvas, Enemy_build

    print ("-----BUILD2------")
    for i in Enemy_build:
        print(i)

    for i in Enemy_build:
        if i >= 1 and i <= 5:
            canvas.create_image(550-40, 417 - (77 * (i-1)), image = image5, anchor = NW)
        if i >= 7 and i <= 11:
            canvas.create_image(450 - (80 * ((i-1)%6)), 7+40, image = image5, anchor = NW)
        if i >= 13 and i <=17:
            canvas.create_image(35+40, 109 + (77*((i-1)%6)), image = image5, anchor = NW)
        if i >= 19 and i <=23:
            canvas.create_image(130 + (77*((i-1)%6)), 520-40, image = image5, anchor = NW)


def setGameInfo():

    global User_Info_money, User_Info_location, Enemy_Info_money, Enemy_Info_location

    Game_Info_window.edit_reset()

    Game_Info_window.insert(tkinter.INSERT, "내 보유 금액 : " + str(User_Info_money) +"\n")
    Game_Info_window.insert(tkinter.INSERT, "내 보유 지역 : ")
    for i in User_Info_location:
        Game_Info_window.insert(tkinter.INSERT,  i + " ")
    Game_Info_window.insert(tkinter.INSERT, "\n")

    Game_Info_window.insert(tkinter.INSERT, "상대 보유 금액 : " + str(Enemy_Info_money) +"\n")
    Game_Info_window.insert(tkinter.INSERT, "상대 보유 지역 : ")
    for i in Enemy_Info_location:
        Game_Info_window.insert(tkinter.INSERT,  i + " ")
    Game_Info_window.insert(tkinter.INSERT, "\n")

#소켓 데이터 읽기 쓰레드 활성화(gettingMsg 함수가 쓰레드로 실행된다)
threading._start_new_thread(gettingMsg,())

#명령어 메뉴
labelInst = tkinter.Label(window, text="메뉴를 고르세요", bg="#383a39", fg="#a1abcd", font=("Helvetica", 16))
labelInst.pack()

#회원가입에 관련된 ui 설정
register_id = tkinter.Entry(window)
register_password = tkinter.Entry(window)
btn_register = tkinter.Button(window, text="회원가입", bg="#383a39", fg="#a1abcd", command=register)
register_id.pack()
register_password.pack()
btn_register.pack()

#로그인에 관련된 ui 설정
btn_login = tkinter.Button(window, text="Login", bg="#383a39", fg="#a1abcd", command=login)
login_id = tkinter.Entry(window)
login_password = tkinter.Entry(window)
login_id.pack()
login_password.pack()
btn_login.pack()
window.mainloop()